﻿
namespace n_HardModule
{
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

using n_GUIcoder;
using n_MyFileObject;
using n_UserModule;
using n_UIModule;
using n_GUIset;
using n_MyFileObjectPanel;
using n_Shape;
using n_MyObjectList;
using n_MyObject;
using n_MainSystemData;
using n_MidPortList;
using n_SimulateObj;

//端口画笔类
public static class PortPenList
{
	public static Pen[] ZZXXLinePen;
	public static Pen[] BackLinePen;
	public static Pen[] ForeLinePen;
	
	public const int Number = 10;
	
	//初始化
	public static void Init()
	{
		ZZXXLinePen = new Pen[Number];
		BackLinePen = new Pen[Number];
		ForeLinePen = new Pen[Number];
		
		int a0 = 200;
		int a1 = 240;
		
		//黑色
		ZZXXLinePen[0] = new Pen( Color.FromArgb(a0, 64, 64, 64), 5 );
		BackLinePen[0] = new Pen( Color.FromArgb(a0, 64, 64, 64), 3 );
		ForeLinePen[0] = new Pen( Color.FromArgb(a1, 64, 64, 64), 1 );
		//暗红
		ZZXXLinePen[1] = new Pen( Color.FromArgb(a0, 128, 64, 64), 5 );
		BackLinePen[1] = new Pen( Color.FromArgb(a0, 128, 64, 64), 3 );
		ForeLinePen[1] = new Pen( Color.FromArgb(a1, 128, 64, 64), 1 );
		//红色
		ZZXXLinePen[2] = new Pen( Color.FromArgb(a0, 240, 64, 64), 5 );
		BackLinePen[2] = new Pen( Color.FromArgb(a0, 240, 64, 64), 3 );
		ForeLinePen[2] = new Pen( Color.FromArgb(a1, 240, 64, 64), 1 );
		//橙色
		ZZXXLinePen[3] = new Pen( Color.FromArgb(a0, 230, 128, 64), 5 );
		BackLinePen[3] = new Pen( Color.FromArgb(a0, 230, 128, 64), 3 );
		ForeLinePen[3] = new Pen( Color.FromArgb(a1, 230, 128, 64), 1 );
		//黄色
		ZZXXLinePen[4] = new Pen( Color.FromArgb(a0, 190, 190, 20), 5 );
		BackLinePen[4] = new Pen( Color.FromArgb(a0, 190, 190, 20), 3 );
		ForeLinePen[4] = new Pen( Color.FromArgb(a1, 190, 190, 20), 1 );
		//绿色
		ZZXXLinePen[5] = new Pen( Color.FromArgb(a0, 84, 220, 84), 5 );
		BackLinePen[5] = new Pen( Color.FromArgb(a0, 84, 220, 84), 3 );
		ForeLinePen[5] = new Pen( Color.FromArgb(a1, 84, 220, 84), 1 );
		//青色
		ZZXXLinePen[6] = new Pen( Color.FromArgb(a0, 30, 210, 210), 5 );
		BackLinePen[6] = new Pen( Color.FromArgb(a0, 30, 210, 210), 3 );
		ForeLinePen[6] = new Pen( Color.FromArgb(a1, 30, 210, 210), 1 );
		//蓝色
		ZZXXLinePen[7] = new Pen( Color.FromArgb(a0, 64, 64, 240), 5 );
		BackLinePen[7] = new Pen( Color.FromArgb(a0, 64, 64, 240), 3 );
		ForeLinePen[7] = new Pen( Color.FromArgb(a1, 64, 64, 240), 1 );
		//紫色
		ZZXXLinePen[8] = new Pen( Color.FromArgb(a0, 200, 64, 240), 5 );
		BackLinePen[8] = new Pen( Color.FromArgb(a0, 200, 64, 240), 3 );
		ForeLinePen[8] = new Pen( Color.FromArgb(a1, 200, 64, 240), 1 );
		//灰色
		ZZXXLinePen[9] = new Pen( Color.FromArgb(a0, 135, 140, 145), 5 );
		BackLinePen[9] = new Pen( Color.FromArgb(a0, 135, 140, 145), 3 );
		ForeLinePen[9] = new Pen( Color.FromArgb(a1, 135, 140, 145), 1 );
	}
}

//端口类
public class Port
{
	int cPortR;
	int cPort2R;
	float PortR;
	float Port2R;
	
	const int DATA_ZWireH = 17;
	//const int DATA_ZWireW = 40;
	const int DATA_ZWireW = 25;
	
	const int POWER_ZWireH = 17;
	const int POWER_ZWireW = 15;
	
	const int MOTOR_ZWireH = 17;
	const int MOTOR_ZWireW = 15;
	
	const int IO3_ZWireH = 17;
	const int IO3_ZWireW = 21;
	
	public string Name;
	
	//2020.12.12 临时名字, 用于LINE端口和主板连接后, 传递主板端口名字. 不能用Name, 因为Name还用于相等时传递类型, 防止冲突
	public string TempName;
	
	public string ClientType;
	public string FuncName;
	public string Style;
	public E_DirType DirType;
	public E_DirType SourceDirType;
	
	//LoadModule
	//GUIcoder 353行 ExtValue = ExtValue.PadRight( 2, '*' );
	
	//默认均为星号* (或者空格(旧版))
	//0: '0' 按照数字序号存储
	//1: '0' CH340主板白色针脚提示
	public string ExtValue;
	public const char ExtNull_old = ' ';
	public const char ExtNull = '*';
	public const char Ext0_DigitalSave = '0';
	public const char Ext1_GD32Unused = '0';
	
	int v_midPortIndex;
	public int MidPortIndex {
		set {
			v_midPortIndex = value;
		}
		get { return v_midPortIndex; }
	}
	
	public float SourceX, SourceY;
	public float X, Y;
	
	public HardModule Owner;
	
	Port v_TargetPort;
	public Port TargetPort {
		set {
			if( v_TargetPort != null ) {
				v_TargetPort.PrePort = null;
			}
			v_TargetPort = value;
			if( v_TargetPort != null ) {
				v_TargetPort.PrePort = this;
			}
		}
		get {
			return v_TargetPort;
		}
	}
	
	public HardModule TargetModule;
	public Port PrePort;
	
	public Port SamePort;
	
	public string SubPortConfig;
	
	public bool isBus;
	
	public bool CanChange;
	public int Index;
	
	static int DefautColorIndex = 0;
	
	//用来表示刷新端口时候是否被处理过
	public bool isDeal;
	
	//颜色索引
	public int ColorIndex;
	
	//------------------------------------------
	//用于电路仿真
	
	public int I_Addr;
	public int V_Addr;
	
	public int Net_Index;
	public int Input_Addr;
	public int Output_Addr;
	
	public int C_Index;
	
	//------------------------------------------
	
	static SolidBrush BackBlockBrush;
	
	static Pen BackLinePenOn1;
	static Pen BackLinePenOn;
	static Pen ForLinePenOn;
	
	
	static Pen INTERFACEBackLinePen;
	static Pen IPortPreLinkPen;
	static Pen PortPreLinkPen;
	
	static Pen HighLightPortPen;
	
	static Pen LineIndexPen;
	
	static Brush bHighLightPortBrush;
	static Brush rHighLightPortBrush;
	static Brush cHighLightPortBrush;
	static Brush mHighLightPortBrush;
	
	static Brush BlackBrush;
	static Pen ADBluePen;
	
	static Font f;
	
	static Random R;
	
	public static int C_Rol = 50;
	bool isZX;
	
	//初始化
	public static void Init()
	{
		ADBluePen = new Pen( Color.FromArgb( 225, 225, 45 ) );
		
		BackBlockBrush = new SolidBrush( Color.FromArgb( 50, 50, 50 ) );
		
		BackLinePenOn1 = new Pen( Color.Olive, 3 );
		BackLinePenOn = new Pen( Color.Yellow, 3 );
		ForLinePenOn = new Pen( Color.Yellow, 1 );
		
		//初始化GDI对象
		LineIndexPen = new Pen( Color.Black, 5 );
		
		if( SystemData.isBlack ) {
			INTERFACEBackLinePen = new Pen( Color.White, 3 );
		}
		else {
			INTERFACEBackLinePen = new Pen( Color.Black, 3 );
		}
		System.Drawing.Drawing2D.AdjustableArrowCap AC = new AdjustableArrowCap( 5, 4, true );
		INTERFACEBackLinePen.StartCap = LineCap.Round;
		INTERFACEBackLinePen.CustomEndCap = AC;
		INTERFACEBackLinePen.DashStyle = DashStyle.Dash;
		
		
		if( SystemData.isBlack ) {
			PortPreLinkPen = new Pen( Color.Silver, 1 );
			IPortPreLinkPen = new Pen( Color.LightGreen, 2 );
		}
		else {
			PortPreLinkPen = new Pen( Color.DarkSeaGreen, 1 );
			IPortPreLinkPen = new Pen( Color.DarkSeaGreen, 2 );
		}
		IPortPreLinkPen.DashStyle = DashStyle.Dash;
		PortPreLinkPen.DashStyle = DashStyle.Dash;
		//PortPreLinkPen.DashStyle = DashStyle.Dot;
		
		HighLightPortPen = new Pen( Color.Yellow, 3 );
		
		if( SystemData.ColorType == 0 ) {
			bHighLightPortBrush = new SolidBrush( Color.FromArgb(0, 128, 255) );
		}
		else {
			bHighLightPortBrush = new SolidBrush( Color.DarkSlateGray );
		}
		
		rHighLightPortBrush = new SolidBrush( Color.Red );
		cHighLightPortBrush = new SolidBrush( Color.Yellow );
		mHighLightPortBrush = new SolidBrush( Color.Yellow );
		
		if( SystemData.ColorType == 0 ) {
			BlackBrush = new SolidBrush( Color.RoyalBlue );
		}
		else {
			BlackBrush = new SolidBrush( Color.FromArgb( 30, 45, 50 ) );
		}
		
		f = new Font( "Courier New", 12 );
		
		R = new Random( System.DateTime.Now.Millisecond );
	}
	
	//构造函数
	public Port( HardModule vOwner, int i, string vName, string vFuncType, string vFuncName, string vStyle, string vSubPortConfig, E_DirType vDirType, float vX, float vY, bool v_isBus, string vExtValue )
	{
		Owner = vOwner;
		Index = i;
		Name = vName;
		ClientType = vFuncType;
		FuncName = vFuncName;
		Style = vStyle;
		SubPortConfig = vSubPortConfig;
		SourceDirType = vDirType;
		DirType = SourceDirType;
		ExtValue = vExtValue;
		
		SourceX = vX;
		SourceY = vY;
		X = vX;
		Y = vY;
		
		SamePort = null;
		
		if( this.FuncName == PortFuncName.ZX ) {
			isZX = true;
			cPortR = 8;
		}
		else {
			isZX = false;
			cPortR = 4;
		}
		
		cPort2R = cPortR * 2;
		
		if( this.FuncName == PortFuncName.VCC ) {
			ColorIndex = 2;
		}
		else if( this.FuncName == PortFuncName.VCCA ) {
			ColorIndex = 2;
		}
		else if( this.FuncName == PortFuncName.VCC6t9V ) {
			ColorIndex = 1;
		}
		else if( this.FuncName == PortFuncName.VCC3_3V ) {
			ColorIndex = 3;
		}
		else if( this.FuncName == PortFuncName.GND ) {
			if( SystemData.ColorType == 0 ) {
				ColorIndex = 6;
			}
			else {
				ColorIndex = 0;
			}
		}
		else {
			
			//打开服务中心时需要加上这一句
			if( R == null ) {
				R = new Random( System.DateTime.Now.Millisecond );
			}
			
			ColorIndex = DefautColorIndex;
			DefautColorIndex += 3 + R.Next( 0, 2 );
			DefautColorIndex %= PortPenList.Number;
			if( DefautColorIndex == 0 || DefautColorIndex == 2 ) {
				DefautColorIndex += 4 + R.Next( 0, 2 );
			}
		}
		
		//首次不能使用封装
		v_midPortIndex = -1;
		//MidPortIndex = -1;
		
		if( FuncName == PortFuncName.LINE ) {
			CanChange = true;
		}
		else {
			CanChange = false;
		}
		
		TargetPort = null;
		
		isBus = v_isBus;
		isDeal = false;
		PortR = cPortR * HardModule.Scale;
		Port2R = cPort2R * HardModule.Scale;
	}
	
	//判断是否为数字序号针脚
	public bool isNumIdxPort()
	{
		return ExtValue[0] == Ext0_DigitalSave;
	}
	
	//判断是否为GD32白色提示针脚
	public bool isNotUsePort()
	{
		return ExtValue[1] == Ext1_GD32Unused;
	}
	
	//重新设置端口的位置
	public void ResetLocation()
	{
		this.X = SourceX * Owner.CScale;
		this.Y = SourceY * Owner.CScale;
		DirType = SourceDirType;
	}
	
	//绘制
	public void Draw1( Graphics g )
	{
		//绘制背景方框
		//g.FillRectangle( BackBlockBrush, StartX + Owner.MidX + X - PortR - 2, StartY + Owner.MidY + Y - PortR - 2, Port2R + 4, Port2R + 4 );
	}
	
	//绘制
	public void Draw2( Graphics g, MyObjectList myObjectList )
	{
		float x = Owner.MidX + X;
		float y = Owner.MidY + Y;
		
		//绘制组件连接
		if( this.TargetModule != null ) {
			float tX = this.TargetModule.MidX;
			float tY = this.TargetModule.MidY;
			
			float OffX = tX - x;
			float OffY = tY - y;
			float R = (float)Math.Sqrt( OffX * OffX + OffY * OffY);
			float A = OffX / R;
			float B = OffY / R;
			float W = this.TargetModule.Width / 2;
			float H = this.TargetModule.Height / 2;
			float MR = (float)Math.Sqrt(W * W + H * H);
			tX -= MR * A;
			tY -= MR * B;
			
			float XLength = Math.Abs( x - tX );
			float YLength = Math.Abs( y - tY );
			float Length = (float)Math.Sqrt( XLength * XLength + YLength * YLength);
			float Rol = Length * C_Rol / 100;
			PointF PA = new PointF( x, y );
			PointF PA1 = GetDirPoint( Rol, PA, this.DirType );
			PointF PB = new PointF( tX, tY );
			PointF PB1 = new PointF( tX, tY );
			
			g.DrawBezier( INTERFACEBackLinePen, PA, PA1, PB1, PB );
			//g.DrawBezier( INTERFACEForeLinePen, PA, PA1, PB1, PB );
		}
		//绘制端口连接
		else if( this.TargetPort != null ) {
			
			if( Owner.PackOwner != null ) {
				return;
			}
			
			float tX = this.TargetPort.X + this.TargetPort.Owner.MidX;
			float tY = this.TargetPort.Y + this.TargetPort.Owner.MidY;
			
			Pen BackLinePen = PortPenList.BackLinePen[ColorIndex];
			if( isZX ) {
				BackLinePen = PortPenList.ZZXXLinePen[ColorIndex];
			}
			Pen ForeLinePen = PortPenList.ForeLinePen[ColorIndex];
			
			//if( G.SimulateMode ) {
			//	BackLinePen.Color = Color.FromArgb( 150, BackLinePen.Color.R, BackLinePen.Color.G, BackLinePen.Color.B );
			//	ForeLinePen.Color = Color.FromArgb( 150, ForeLinePen.Color.R, ForeLinePen.Color.G, ForeLinePen.Color.B );
			//}
			//else {
			//	BackLinePen.Color = Color.FromArgb( 150, BackLinePen.Color.R, BackLinePen.Color.G, BackLinePen.Color.B );
			//	ForeLinePen.Color = Color.FromArgb( 250, ForeLinePen.Color.R, ForeLinePen.Color.G, ForeLinePen.Color.B );
			//}
			if( this == myObjectList.MouseOnPort ||
			    this.Owner.Index == G.CGPanel.TakeMoIndex && this.Index == G.CGPanel.TakePoIndex ) {
				BackLinePen = BackLinePenOn;
				ForeLinePen = ForLinePenOn;
			}
			float XLength = Math.Abs( x - tX );
			float YLength = Math.Abs( y - tY );
			float Length = (float)Math.Sqrt( XLength * XLength + YLength * YLength);
			float Rol = Length * C_Rol / 100;
			//if( !isBus ) {
			//	Rol = Length * 8 / 10;
			//}
			if( MidPortIndex != -1 && C_Rol != 0 ) {
				Rol = 50;
			}
			PointF PA = new PointF( x, y );
			PointF PA1 = GetDirPoint( Rol, PA, this.DirType );
			PointF PB = new PointF( tX, tY );
			PointF PB1 = GetDirPoint( Rol, PB, this.TargetPort.DirType );
			
			if( MidPortIndex == -1 ) {
				g.DrawBezier( BackLinePen, PA, PA1, PB1, PB );
				g.DrawBezier( ForeLinePen, PA, PA1, PB1, PB );
			}
			else {
				
				myObjectList.GPanel.myMidPortList.SetPort( MidPortIndex, this, TargetPort );
				
				int CLength = G.CGPanel.myMidPortList.GetLength( MidPortIndex );
				PointF[] pp = new PointF[4+CLength*3];
				pp[0] = PA;
				pp[1] = PA1;
				for( int i = 0; i < CLength; ++i ) {
					MidPort p = Owner.myObjectList.GPanel.myMidPortList.GetPoint( MidPortIndex, i );
					PointF PO = new PointF( p.X, p.Y );
					pp[2 + i * 3 + 1] = PO;
				}
				pp[2+CLength*3] = PB1;
				pp[3+CLength*3] = PB;
				
				for( int i = 0; i < CLength; ++i ) {
					MidPort p = Owner.myObjectList.GPanel.myMidPortList.GetPoint( MidPortIndex, i );
					
					PointF PO = new PointF( p.X, p.Y );
					
					float ox = pp[2 + i * 3 + 4].X - pp[2 + i * 3 - 2].X;
					float oy = pp[2 + i * 3 + 4].Y - pp[2 + i * 3 - 2].Y;
					ox /= 7;
					oy /= 7;
					if( C_Rol == 0 ) {
						ox = 0;
						oy = 0;
					}
					
					PointF PO1 = new PointF( p.X - ox, p.Y - oy );
					PointF PO2 = new PointF( p.X + ox, p.Y + oy );
					
					pp[2 + i * 3] = PO1;
					pp[2 + i * 3 + 2] = PO2;
					
					//g.FillRectangle( Brushes.SlateGray, PO.X, PO.Y, 4, 4 );
					
					//g.FillRectangle( Brushes.Red, PO1.X, PO1.Y, 4, 4 );
					//g.FillRectangle( Brushes.Blue, PO2.X, PO2.Y, 4, 4 );
				}
				
				if( C_Rol != 0 ) {
					g.DrawBeziers( BackLinePen, pp );
					g.DrawBeziers( ForeLinePen, pp );
				}
				else {
					g.DrawLines( BackLinePen, pp );
					g.DrawLines( ForeLinePen, pp );
				}
			}
		}
		//绘制端口连接
		else if( this.TargetPort == null && this.MidPortIndex != -1 ) {
			
			if( Owner.PackOwner != null ) {
				return;
			}
			if( G.CGPanel.myMidPortList.GetLength( MidPortIndex ) == 0 ) {
				G.CGPanel.myMidPortList.Delete( MidPortIndex );
				MidPortIndex = -1;
				return;
			}
			MidPort pend = Owner.myObjectList.GPanel.myMidPortList.GetPoint( MidPortIndex, G.CGPanel.myMidPortList.GetLength( MidPortIndex ) - 1 );
			
			Pen BackLinePen = PortPenList.BackLinePen[ColorIndex];
			Pen ForeLinePen = PortPenList.ForeLinePen[ColorIndex];
			
			if( this == myObjectList.MouseOnPort ||
			    this.Owner.Index == G.CGPanel.TakeMoIndex && this.Index == G.CGPanel.TakePoIndex ) {
				BackLinePen = BackLinePenOn;
				ForeLinePen = ForLinePenOn;
			}
			float XLength = Math.Abs( x - pend.X );
			float YLength = Math.Abs( y - pend.Y );
			float Length = (float)Math.Sqrt( XLength * XLength + YLength * YLength);
			float Rol = Length * C_Rol / 100;
			//if( !isBus ) {
			//	Rol = Length * 8 / 10;
			//}
			if( MidPortIndex != -1 && C_Rol != 0 ) {
				Rol = 50;
			}
			PointF PA = new PointF( x, y );
			PointF PA1 = GetDirPoint( Rol, PA, this.DirType );
			
			myObjectList.GPanel.myMidPortList.SetPort( MidPortIndex, this, TargetPort );
			
			int CLength = G.CGPanel.myMidPortList.GetLength( MidPortIndex );
			PointF[] pp = new PointF[4+CLength*3];
			pp[0] = PA;
			pp[1] = PA1;
			for( int i = 0; i < CLength; ++i ) {
				MidPort p = Owner.myObjectList.GPanel.myMidPortList.GetPoint( MidPortIndex, i );
				PointF PO = new PointF( p.X, p.Y );
				pp[2 + i * 3 + 1] = PO;
			}
			pp[2+CLength*3] = new PointF( pend.X, pend.Y );
			pp[3+CLength*3] = new PointF( pend.X, pend.Y );
			
			for( int i = 0; i < CLength; ++i ) {
				MidPort p = Owner.myObjectList.GPanel.myMidPortList.GetPoint( MidPortIndex, i );
				
				float ox = pp[2 + i * 3 + 4].X - pp[2 + i * 3 - 2].X;
				float oy = pp[2 + i * 3 + 4].Y - pp[2 + i * 3 - 2].Y;
				ox /= 7;
				oy /= 7;
				if( C_Rol == 0 ) {
					ox = 0;
					oy = 0;
				}
				
				PointF PO1 = new PointF( p.X - ox, p.Y - oy );
				PointF PO2 = new PointF( p.X + ox, p.Y + oy );
				
				pp[2 + i * 3] = PO1;
				pp[2 + i * 3 + 2] = PO2;
				
				//g.FillRectangle( Brushes.SlateGray, PO.X, PO.Y, 4, 4 );
				
				//g.FillRectangle( Brushes.Red, PO1.X, PO1.Y, 4, 4 );
				//g.FillRectangle( Brushes.Blue, PO2.X, PO2.Y, 4, 4 );
			}
			
			if( C_Rol != 0 ) {
				g.DrawBeziers( BackLinePen, pp );
				g.DrawBeziers( ForeLinePen, pp );
			}
			else {
				g.DrawLines( BackLinePen, pp );
				g.DrawLines( ForeLinePen, pp );
			}
		}
		//这里绘制预连接(虚线表示,用来提示用户合法的连接方式)
		else if( //n_ImagePanel.ImagePanel.Flash &&
		        (isBus || Owner.myObjectList.MouseOnObject != null || Owner.myObjectList.SelectPort != null ) &&
		        this.FuncName != PortFuncName.PULL &&
		        this.FuncName != PortFuncName.UNUSED &&
		        this.FuncName != PortFuncName.C_Analog &&
		        this.FuncName != PortFuncName.C_Digital &&
		        !myObjectList.isModuleLib &&
		        Owner.PackOwner == null &&
		        (Owner.myObjectList.MouseOnObject == Owner || Owner.myObjectList.SelectPort == this ) &&
		        (Owner.myObjectList.MouseOnPort == null || Owner.myObjectList.MouseOnPort == this ) &&
		        this.ClientType == PortClientType.CLIENT ) { //&&
		        //this.FuncName != PortFuncName.VCC &&
		        //this.FuncName != PortFuncName.GND &&
		        //this.FuncName != PortFuncName.IN &&
		        //this.FuncName != PortFuncName.OUT &&
		        //this.FuncName != PortFuncName.IN + "," + PortFuncName.OUT ) {
			
			foreach( MyObject mo in myObjectList ) {
		    
				if( !(mo is HardModule) ) {
					continue;
				}
				HardModule mm = (HardModule)mo;
				if( !mm.isControlModule ) {
					//continue;
				}
				if( mm == this.Owner ) {
					continue;
				}
				//搜索目标端口
				Port[] PortList = mm.PORTList;
				for( int pi = 0; pi < PortList.Length; ++pi ) {
					
					//判断目标主板的类型是否允许连接提示
					if( !mm.PackOpenMPort &&
					    (mm.PackOwner!=null) &&
					    (mm.ImageName!=SPMoudleName.SYS_iport) &&
					    (PortList[ pi ].FuncName != PortFuncName.UART) ) {
						continue;
					}
					
					if( PortList[ pi ].ClientType != PortClientType.MASTER && this.FuncName != PortFuncName.PULL ) {
						continue;
					}
					/*
					if( PortList[ pi ].FuncName.IndexOf( this.FuncName ) != -1 ||
					   ( this.FuncName == ",OUT," &&
					    (PortList[ pi ].FuncName == ",VCC," ||
					     PortList[ pi ].FuncName == ",VCC3.3V," ||
					     PortList[ pi ].FuncName == ",GND,") ) ) {
					*/
					//不给用户提示串口下载线, 不建议连接到这两个线上
					if( PortList[ pi ].FuncName.IndexOf( PortFuncName.RxD ) != -1 || PortList[ pi ].FuncName.IndexOf( PortFuncName.TxD ) != -1 ) {
						if( this.FuncName.IndexOf( PortFuncName.RxD ) == -1 && this.FuncName.IndexOf( PortFuncName.TxD ) == -1 ) {
							continue;
						}
					}
					//判断是否为串口, 允许忽略串口序号的不同
					bool isRx = this.FuncName == PortFuncName.RxD;
					isRx &= PortList[ pi ].FuncName.IndexOf( PortFuncName.RxDn ) != -1;
					bool isTx = this.FuncName == PortFuncName.TxD;
					isTx &= PortList[ pi ].FuncName.IndexOf( PortFuncName.TxDn ) != -1;
					
					//忽略VEX模式INT类型的需求
					bool ignVexINT = false;
					if( GUIcoder.cputype1 == "VM" &&
					    (this.FuncName == PortFuncName.INT) &&
					    ((PortList[ pi ].FuncName + ",").IndexOf( PortFuncName.IN ) != -1) ) {
						ignVexINT = true;
					}
					string fname = this.FuncName;
					if( this.FuncName == PortFuncName.VCCA ) {
						if( GUIcoder.isVCC3_3 ) {
							fname = PortFuncName.VCC3_3V;
						}
						else {
							fname = PortFuncName.VCC;
						}
					}
					if( PortList[ pi ].FuncName.IndexOf( fname ) != -1 ||
					    fname == PortFuncName.PULL ||
						isRx || isTx || ignVexINT ) {
						float tX = PortList[ pi ].X + PortList[ pi ].Owner.MidX;
						float tY = PortList[ pi ].Y + PortList[ pi ].Owner.MidY;
						float XLength = Math.Abs( x - tX );
						float YLength = Math.Abs( y - tY );
						float Length = (float)Math.Sqrt( XLength * XLength + YLength * YLength);
						float Rol = Length * 50 / 100;
						PointF PA = new PointF( x, y );
						PointF PA1 = GetDirPoint( Rol, PA, this.DirType );
						PointF PB = new PointF( tX, tY );
						PointF PB1 = GetDirPoint( Rol, PB, PortList[ pi ].DirType );
						
						
						if( fname == PortFuncName.VCC ||
			    			fname == PortFuncName.VCC3_3V ||
			    			fname == PortFuncName.VCC6t9V ) {
							PortPreLinkPen.Color = Color.Coral;
						}
						else if( fname == PortFuncName.GND ) {
							PortPreLinkPen.Color = Color.CornflowerBlue;
						}
						else {
							PortPreLinkPen.Color = Color.MediumSeaGreen;
						}
						
						
						g.DrawBezier( PortPreLinkPen, PA, PA1, PB1, PB );
					}
				}
				//搜索目标端口
				PortList = mm.ZWireList;
				for( int pi = 0; this.isBus && pi < PortList.Length; ++pi ) {
					if( PortList[ pi ].ClientType != PortClientType.MASTER ) {
						continue;
					}
					if( PortList[ pi ].SubPortConfig == null || this.SubPortConfig == null || PortList[ pi ].SubPortConfig.Length != this.SubPortConfig.Length ) {
					//	continue;
					}
					if( PortList[ pi ].SubPortConfig != null && this.SubPortConfig != null && PortList[ pi ].SubPortConfig.Length == this.SubPortConfig.Length ) {
						for( int i = 0; i < this.SubPortConfig.Length; i++ ) {
							if( this.SubPortConfig[i] == '1' && PortList[ pi ].SubPortConfig[i] == '0' ) {
								goto next;
							}
						}
					}
					if( PortList[ pi ].FuncName.IndexOf( this.FuncName ) != -1 ) {
						
						float tX = PortList[ pi ].X + PortList[ pi ].Owner.MidX;
						float tY = PortList[ pi ].Y + PortList[ pi ].Owner.MidY;
						float XLength = Math.Abs( x - tX );
						float YLength = Math.Abs( y - tY );
						float Length = (float)Math.Sqrt( XLength * XLength + YLength * YLength);
						float Rol = Length * C_Rol / 100;
						PointF PA = new PointF( x, y );
						PointF PA1 = GetDirPoint( Rol, PA, this.DirType );
						PointF PB = new PointF( tX, tY );
						PointF PB1 = GetDirPoint( Rol, PB, PortList[ pi ].DirType );
						
						g.DrawBezier( IPortPreLinkPen, PA, PA1, PB1, PB );
					}
					next:;
				}
			}
		}
		//鼠标放到模块上时, 显示同名端口 (用直线连接)
		if( Owner.myObjectList.isModuleLib ) {
			return;
		}
		if( Owner.myObjectList.MouseOnObject == Owner ) {
			if( this.SamePort != null ) {
				
				float xx = Owner.MidX + X;
				float yy = Owner.MidY + Y;
				
				float txx = this.SamePort.X + this.SamePort.Owner.MidX;
				float tyy = this.SamePort.Y + this.SamePort.Owner.MidY;
				
				if( n_ImagePanel.ImagePanel.Flash ) {
					g.DrawLine( BackLinePenOn1, xx, yy, txx, tyy );
					g.DrawLine( ForLinePenOn, xx, yy, txx, tyy );
				}
				//else {
				//	g.DrawLine( GNDBackLinePen, xx, yy, txx, tyy );
				//	g.DrawLine( GNDForeLinePen, xx, yy, txx, tyy );
				//}
			}
		}
	}
	
	//绘制
	public void Draw3( Graphics g )
	{
		float to_MidX = Owner.SX + (float)Owner.Width/2;// - 0.5f;
		float to_MidY = Owner.SY + (float)Owner.Height/2;// - 0.5f;
		
		//绘制总线式节点
		if( isBus ) {
			Size R0 = GetArea0();
			Size R = GetArea();
			Brush s0 = null;
			Brush s = null;
			
			//绘制电源端口连接线
			if( FuncName == ZWireFuncName.POWER ) {
				s = Brushes.Orange;
				s0 = Brushes.Orange;
				g.FillRectangle( s, to_MidX + X - R.Width / 2, to_MidY + Y - R.Height / 2, R.Width, R.Height );
				g.FillRectangle( s0, to_MidX + X -R0.Width / 2, to_MidY + Y - R0.Height / 2, R0.Width, R0.Height );
			}
			//绘制电机端口连接线
			else if( FuncName == ZWireFuncName.MOTOR ) {
				s = Brushes.LightGreen;
				s0 = Brushes.LightGreen;
				g.FillRectangle( s, to_MidX + X - R.Width / 2, to_MidY + Y - R.Height / 2, R.Width, R.Height );
				g.FillRectangle( s0, to_MidX + X -R0.Width / 2, to_MidY + Y - R0.Height / 2, R0.Width, R0.Height );
			}
			//绘制3线制端口
			else if( FuncName == ZWireFuncName.IO3 ) {
				s = Brushes.SlateBlue;
				s0 = Brushes.SlateBlue;
				g.FillRectangle( s, to_MidX + X - R.Width / 2, to_MidY + Y - R.Height / 2, R.Width, R.Height );
				g.FillRectangle( s0, to_MidX + X -R0.Width / 2, to_MidY + Y - R0.Height / 2, R0.Width, R0.Height );
			}
			//绘制数据端口连接线
			else {
//				if ( FuncType == PortFuncType.CLIENT ) {
//					s = Brushes.SlateBlue;
//					s0 = Brushes.SlateBlue;
//				}
//				else {
//					s = Brushes.SlateBlue;
//					s0 = Brushes.SlateBlue;
//				}
				if ( Style == PortStyle.IO6 ) {
					//s = Brushes.SlateBlue;
					//s0 = Brushes.SlateBlue;
					s = Brushes.CornflowerBlue;
					s0 = Brushes.LightSteelBlue;
					//...
				}
				else if ( Style == PortStyle.IO3 ) {
					s = Brushes.Silver;
					s0 = Brushes.Silver;
				}
				else {
					s = Brushes.SlateBlue;
					s0 = Brushes.SlateBlue;
				}
				g.FillRectangle( s, to_MidX + X - R.Width / 2, to_MidY + Y - R.Height / 2, R.Width, R.Height );
				g.FillRectangle( s0, to_MidX + X -R0.Width / 2, to_MidY + Y - R0.Height / 2, R0.Width, R0.Height );
			}
		}
		//绘制单线连接式节点 如果已连接就不再绘制小圆点
		//this.TargetPort == null 忽略此条件
		else {
			
			if( ClientType == PortClientType.CLIENT && Owner.PackOwner != null ) {
				return;
			}
			Brush s = null;
			Pen p = null;
			
			//if( !Owner.isYuanJian ) {
			//if( (Owner.myObjectList.MouseOnObject == Owner || Owner.isControlModule || Owner.ImageName == SPMoudleName.SYS_iport ) ) {
				if( FuncName == PortFuncName.VCC ) {
					s = Brushes.Firebrick;
					p = Pens.DarkRed;
				}
				else if( FuncName == PortFuncName.VCC3_3V ) {
					s = Brushes.IndianRed;
					p = Pens.Firebrick;
				}
				else if( FuncName == PortFuncName.VCC6t9V ) {
					s = Brushes.DarkRed;
					p = Pens.Maroon;
				}
				else if( FuncName == PortFuncName.VCCA ) {
					s = Brushes.IndianRed;
					p = Pens.DarkRed;
				}
				else if( FuncName == PortFuncName.GND ) {
					
					s = BlackBrush;
					if( SystemData.ColorType == 0 ) {
						p = Pens.MediumBlue;
					}
					else {
						p = Pens.SlateGray;
					}
				}
				else if( FuncName == PortFuncName.UNUSED ) {
					s = Brushes.Silver;
					p = Pens.DarkOliveGreen;
				}
				else if ( ClientType == PortClientType.CLIENT ) {
					
					if( FuncName.IndexOf( PortFuncName.AD ) != -1 ) {
						s = Brushes.DarkKhaki;
						p = Pens.Olive;
					}
					else {
						s = Brushes.MediumSeaGreen;
						p = Pens.Green;
					}
				}
				else {
					if( FuncName.IndexOf( PortFuncName.AD ) != -1 ) {
						s = Brushes.DarkKhaki;
						p = Pens.Olive;
					}
					else if( isNotUsePort() ) {
						s = Brushes.WhiteSmoke;
						p = Pens.Gray;
					}
					else {
						s = Brushes.MediumSeaGreen;
						p = Pens.Green;
					}
				}
			//}
			//else {
			//	s = Brushes.LightSlateGray;
			//	p = Pens.SlateGray;
			//}
			
			//除了主控板的M端口以外都不显示
			if( G.SimulateMode || Owner.myObjectList.MouseOnObject != Owner &&
			   (ClientType == PortClientType.CLIENT || ClientType == PortClientType.MASTER && !Owner.isControlModule ) ) {
				
				if( Owner.isYuanJian ) {
					return;
				}
			}
			if( CanChange && Owner.ImageName == SPMoudleName.mbb ) {
				if( FuncName == PortFuncName.LINE ) {
					p = Pens.SlateGray;
				}
				if( Owner.myObjectList.MouseOnPort == this ) {
					p = Pens.Purple;
				}
				g.DrawRectangle( p, to_MidX + X - PortR, to_MidY + Y - PortR, Port2R, Port2R );
			}
			else {
				g.FillRectangle( s, to_MidX + X - PortR, to_MidY + Y - PortR, Port2R, Port2R );
				g.DrawRectangle( p, to_MidX + X - PortR, to_MidY + Y - PortR, Port2R, Port2R );
			}
		}
	}
	
	//绘制轨迹图索引
	public void DrawLineIndex( Graphics g, MyObjectList myObjectList )
	{
		float x = Owner.MidX + X;
		float y = Owner.MidY + Y;
		
		//绘制端口连接
		if( this.TargetPort != null ) {
			
			if( Owner.PackOwner != null ) {
				return;
			}
			
			float tX = this.TargetPort.X + this.TargetPort.Owner.MidX;
			float tY = this.TargetPort.Y + this.TargetPort.Owner.MidY;
			
			float XLength = Math.Abs( x - tX );
			float YLength = Math.Abs( y - tY );
			float Length = (float)Math.Sqrt( XLength * XLength + YLength * YLength);
			float Rol = Length * C_Rol / 100;
			//if( !isBus ) {
			//	Rol = Length * 8 / 10;
			//}
			if( MidPortIndex != -1 && C_Rol != 0 ) {
				Rol = 50;
			}
			PointF PA = new PointF( x, y );
			PointF PA1 = GetDirPoint( Rol, PA, this.DirType );
			PointF PB = new PointF( tX, tY );
			PointF PB1 = GetDirPoint( Rol, PB, this.TargetPort.DirType );
			
			LineIndexPen.Color = Color.FromArgb( this.Owner.Index % 256, this.Index % 256, this.Owner.Index / 256 );
			
			if( MidPortIndex == -1 ) {
				g.DrawBezier( LineIndexPen, PA, PA1, PB1, PB );
			}
			else {
				int CLength = G.CGPanel.myMidPortList.GetLength( MidPortIndex );
				PointF[] pp = new PointF[4+CLength*3];
				pp[0] = PA;
				pp[1] = PA1;
				for( int i = 0; i < CLength; ++i ) {
					MidPort p = Owner.myObjectList.GPanel.myMidPortList.GetPoint( MidPortIndex, i );
					PointF PO = new PointF( p.X, p.Y );
					pp[2 + i * 3 + 1] = PO;
				}
				pp[2+CLength*3] = PB1;
				pp[3+CLength*3] = PB;
				
				for( int i = 0; i < CLength; ++i ) {
					MidPort p = Owner.myObjectList.GPanel.myMidPortList.GetPoint( MidPortIndex, i );
					
					PointF PO = new PointF( p.X, p.Y );
					
					float ox = pp[2 + i * 3 + 4].X - pp[2 + i * 3 - 2].X;
					float oy = pp[2 + i * 3 + 4].Y - pp[2 + i * 3 - 2].Y;
					ox /= 7;
					oy /= 7;
					if( C_Rol == 0 ) {
						ox = 0;
						oy = 0;
					}
					PointF PO1 = new PointF( p.X - ox, p.Y - oy );
					PointF PO2 = new PointF( p.X + ox, p.Y + oy );
					
					pp[2 + i * 3] = PO1;
					pp[2 + i * 3 + 2] = PO2;
					
					//g.FillRectangle( Brushes.SlateGray, PO.X, PO.Y, 4, 4 );
					
					//g.FillRectangle( Brushes.Red, PO1.X, PO1.Y, 4, 4 );
					//g.FillRectangle( Brushes.Blue, PO2.X, PO2.Y, 4, 4 );
				}
				
				if( C_Rol != 0 ) {
					g.DrawBeziers( LineIndexPen, pp );
				}
				else {
					g.DrawLines( LineIndexPen, pp );
				}
			}
		}
		//绘制端口连接
		else if( this.MidPortIndex != -1 ) {
			
			if( Owner.PackOwner != null ) {
				return;
			}
			if( G.CGPanel.myMidPortList.GetLength( MidPortIndex ) == 0 ) {
				G.CGPanel.myMidPortList.Delete( MidPortIndex );
				MidPortIndex = -1;
				return;
			}
			MidPort pend = Owner.myObjectList.GPanel.myMidPortList.GetPoint( MidPortIndex, G.CGPanel.myMidPortList.GetLength( MidPortIndex ) - 1 );
			
			Pen BackLinePen = PortPenList.BackLinePen[ColorIndex];
			Pen ForeLinePen = PortPenList.ForeLinePen[ColorIndex];
			
			if( this == myObjectList.MouseOnPort ||
			    this.Owner.Index == G.CGPanel.TakeMoIndex && this.Index == G.CGPanel.TakePoIndex ) {
				BackLinePen = BackLinePenOn;
				ForeLinePen = ForLinePenOn;
			}
			float XLength = Math.Abs( x - pend.X );
			float YLength = Math.Abs( y - pend.Y );
			float Length = (float)Math.Sqrt( XLength * XLength + YLength * YLength);
			float Rol = Length * C_Rol / 100;
			//if( !isBus ) {
			//	Rol = Length * 8 / 10;
			//}
			if( MidPortIndex != -1 && C_Rol != 0 ) {
				Rol = 50;
			}
			PointF PA = new PointF( x, y );
			PointF PA1 = GetDirPoint( Rol, PA, this.DirType );
			
			//myObjectList.GPanel.myMidPortList.SetPort( MidPortIndex, this, TargetPort );
			
			LineIndexPen.Color = Color.FromArgb( this.Owner.Index % 256, this.Index % 256, (this.Owner.Index / 256) * 16 + this.Index / 256 );
			
			int CLength = G.CGPanel.myMidPortList.GetLength( MidPortIndex );
			PointF[] pp = new PointF[4+CLength*3];
			pp[0] = PA;
			pp[1] = PA1;
			for( int i = 0; i < CLength; ++i ) {
				MidPort p = Owner.myObjectList.GPanel.myMidPortList.GetPoint( MidPortIndex, i );
				PointF PO = new PointF( p.X, p.Y );
				pp[2 + i * 3 + 1] = PO;
			}
			pp[2+CLength*3] = new PointF( pend.X, pend.Y );
			pp[3+CLength*3] = new PointF( pend.X, pend.Y );
			
			for( int i = 0; i < CLength; ++i ) {
				MidPort p = Owner.myObjectList.GPanel.myMidPortList.GetPoint( MidPortIndex, i );
				
				float ox = pp[2 + i * 3 + 4].X - pp[2 + i * 3 - 2].X;
				float oy = pp[2 + i * 3 + 4].Y - pp[2 + i * 3 - 2].Y;
				ox /= 7;
				oy /= 7;
				if( C_Rol == 0 ) {
					ox = 0;
					oy = 0;
				}
				
				PointF PO1 = new PointF( p.X - ox, p.Y - oy );
				PointF PO2 = new PointF( p.X + ox, p.Y + oy );
				
				pp[2 + i * 3] = PO1;
				pp[2 + i * 3 + 2] = PO2;
				
				//g.FillRectangle( Brushes.SlateGray, PO.X, PO.Y, 4, 4 );
				
				//g.FillRectangle( Brushes.Red, PO1.X, PO1.Y, 4, 4 );
				//g.FillRectangle( Brushes.Blue, PO2.X, PO2.Y, 4, 4 );
			}
			
			if( C_Rol != 0 ) {
				g.DrawBeziers( LineIndexPen, pp );
			}
			else {
				g.DrawLines( LineIndexPen, pp );
			}
		}
		else {
			//...
		}
	}
	
	//绘制鼠标悬停端口
	public void DrawHighLight( Graphics g )
	{
		if( G.SimulateMode ) {
			//return;
		}
		if( ClientType == PortClientType.CLIENT && Owner.PackOwner != null ) {
			return;
		}
		if( Owner.ImageName == SPMoudleName.mbb ) {
			//n_Debug.Mes.Message = Name + "(" + FuncName + ")" + (ClientType == PortClientType.MASTER? "M": "C");
			return;
		}
		float to_MidX = Owner.SX + (float)Owner.Width/2;
		float to_MidY = Owner.SY + (float)Owner.Height/2;
		
		//绘制实心端口高亮
		Brush HighLightPortBrush = null;
		if( isBus ) {
			if( ClientType == PortClientType.CLIENT ) {
				HighLightPortBrush = Brushes.LightBlue;
			}
			else {
				HighLightPortBrush = Brushes.LightCyan;
			}
			g.DrawRectangle( HighLightPortPen,
			                to_MidX + X - GetArea().Width / 2,
			                to_MidY + Y -  GetArea().Height / 2,
			                GetArea().Width,  GetArea().Height );
		}
		else {
			if( n_ImagePanel.ImagePanel.Flash ) {
				//return;
			}
			Pen LinePen = Pens.White;
			Brush TextBrush = Brushes.White;
			
			Brush BackBrush;
			if( SystemData.isBlack ) {
				BackBrush = Brushes.DarkGray;
			}
			else {
				BackBrush = Brushes.DimGray;
			}
			
			if( FuncName == PortFuncName.VCC ) {
				HighLightPortBrush = rHighLightPortBrush;
				BackBrush = Brushes.Red;
			}
			else if( FuncName == PortFuncName.VCC3_3V ) {
				HighLightPortBrush = rHighLightPortBrush;
				BackBrush = Brushes.Orange;
			}
			else if( FuncName == PortFuncName.VCC6t9V ) {
				HighLightPortBrush = rHighLightPortBrush;
				BackBrush = Brushes.Firebrick;
			}
			else if( FuncName == PortFuncName.GND ) {
				HighLightPortBrush = bHighLightPortBrush;
				
				/*
				if( SystemData.ColorType == 0 ) {
					BackBrush = Brushes.Gray;
				}
				else {
					BackBrush = Brushes.Blue;
				}
				*/
				BackBrush = BlackBrush;
			}
			else if( ClientType == PortClientType.CLIENT ) {
				HighLightPortBrush = cHighLightPortBrush;
			}
			else {
				HighLightPortBrush = mHighLightPortBrush;
			}
			g.FillEllipse( HighLightPortBrush,
			              to_MidX + X - PortR,
			              to_MidY + Y - PortR,
			              Port2R, Port2R );
			
			//显示文本信息
			string mes = null;
			if( TempName == null ) {
				mes = Name + " (" + FuncName + ")";
			}
			else {
				mes = TempName + " (" + FuncName + ")";
			}
			
			if( ClientType == PortClientType.CLIENT ) {
				if( FuncName == PortFuncName.RxD ) {
					mes = "TxD";
				}
				if( FuncName == PortFuncName.TxD ) {
					mes = "RxD";
				}
			}
			
			if( TargetPort != null ) {
				mes += "\n" + TargetPort.Owner.Name + ":" + TargetPort.Name;
			}
			SizeF size = g.MeasureString( mes, f );
			int x = (int)(to_MidX + X);
			int y = (int)(to_MidY + Y);
			int mesX = 0;
			int mesY = 0;
			Point[] pt = null;
			if( DirType == n_UserModule.E_DirType.RIGHT ) {
				pt = new Point[ 5 ];
				pt[ 0 ] = new Point( x + 5, y );
				pt[ 1 ] = new Point( x + 20, y - (int)size.Height / 2 );
				pt[ 2 ] = new Point( x + 20 + (int)size.Width, y - (int)size.Height / 2 );
				pt[ 3 ] = new Point( x + 20 + (int)size.Width, y + (int)size.Height / 2  );
				pt[ 4 ] = new Point( x + 20, y + (int)size.Height / 2  );
				mesX = x + 20;
				mesY = y - (int)size.Height / 2 + 1;
			}
			else if( DirType == n_UserModule.E_DirType.LEFT ) {
				pt = new Point[ 5 ];
				pt[ 0 ] = new Point( x - 5, y );
				pt[ 1 ] = new Point( x - 20, y - (int)size.Height / 2 );
				pt[ 2 ] = new Point( x - 20 - (int)size.Width, y - (int)size.Height / 2 );
				pt[ 3 ] = new Point( x - 20 - (int)size.Width, y + (int)size.Height / 2  );
				pt[ 4 ] = new Point( x - 20, y + (int)size.Height / 2  );
				mesX = x - (int)size.Width - 20;
				mesY = y - (int)size.Height / 2 + 1;
			}
			else if( DirType == n_UserModule.E_DirType.UP ) {
				pt = new Point[ 7 ];
				pt[ 0 ] = new Point( x, y - 5 );
				pt[ 1 ] = new Point( x - 11, y - 20 );
				pt[ 2 ] = new Point( x - (int)size.Width / 2, y - 20 );
				pt[ 3 ] = new Point( x - (int)size.Width / 2, y - 20 - (int)size.Height );
				pt[ 4 ] = new Point( x + (int)size.Width / 2, y - 20 - (int)size.Height );
				pt[ 5 ] = new Point( x + (int)size.Width / 2, y - 20 );
				pt[ 6 ] = new Point( x + 11, y - 20  );
				mesX = x - (int)size.Width / 2;
				mesY = y - 20 - (int)size.Height;
			}
			else {
				pt = new Point[ 7 ];
				pt[ 0 ] = new Point( x, y + 5 );
				pt[ 1 ] = new Point( x - 11, y + 20 );
				pt[ 2 ] = new Point( x - (int)size.Width / 2, y + 20 );
				pt[ 3 ] = new Point( x - (int)size.Width / 2, y + 20 + (int)size.Height );
				pt[ 4 ] = new Point( x + (int)size.Width / 2, y + 20 + (int)size.Height );
				pt[ 5 ] = new Point( x + (int)size.Width / 2, y + 20 );
				pt[ 6 ] = new Point( x + 11, y + 20  );
				mesX = x - (int)size.Width / 2;
				mesY = y + 20;
			}
//			g.FillClosedCurve( Brushes.White, pt, FillMode.Winding, 0.1F );
//			g.DrawClosedCurve( LinePen, pt, 0.1F, FillMode.Winding );
//			g.DrawString( mes, f, TextBrush, mesX, mesY );
			
			g.FillClosedCurve( BackBrush, pt, FillMode.Winding, 0.1F );
			g.DrawClosedCurve( LinePen, pt, 0.1F, FillMode.Winding );
			g.DrawString( mes, f, TextBrush, mesX, mesY );
		}
	}
	
	//绘制选中端口
	public void DrawSelect( Graphics g )
	{
		g.DrawEllipse( HighLightPortPen,
			                Owner.MidX + X - PortR,
			                Owner.MidY + Y - PortR,
			                Port2R, Port2R );
	}
	
	//判断鼠标是否在端口上
	public bool isMouseInPort( int mX, int mY )
	{
		int offX = mX - Owner.MidX;
		int offY = mY - Owner.MidY;
		
		if( !isBus ) {
			if( offX >= X - PortR - 1 && offX <= X + PortR + 1 &&
				offY >= Y - PortR - 1 && offY <= Y + PortR + 1 ) {
				return true;
			}
			else {
				return false;
			}
			/*
			if( offX >= X - PortR && offX <= X + PortR &&
				offY >= Y - PortR && offY <= Y + PortR ) {
				return true;
			}
			else {
				return false;
			}
			*/
		}
		else {
			if( offX >= X - GetArea().Width / 2 && offX <= X +  GetArea().Width / 2 &&
				offY >= Y - GetArea().Height / 2 && offY <= Y +  GetArea().Height / 2 ) {
				return true;
			}
			else {
				return false;
			}
		}
	}
	
	//根据方向信息转换一个坐标的方向坐标
	public static PointF GetDirPoint( float Power, PointF p, E_DirType dir )
	{
		switch( dir ) {
			case E_DirType.UP:		return new PointF( p.X, p.Y - Power );
			case E_DirType.DOWN:	return new PointF( p.X, p.Y + Power );
			case E_DirType.LEFT:	return new PointF( p.X - Power, p.Y );
			case E_DirType.RIGHT:	return new PointF( p.X + Power, p.Y );
			case E_DirType.NONE:	return new PointF( p.X, p.Y );
			default:				return Point.Empty;
		}
	}
	
	//获取端口尺寸
	Size GetArea()
	{
		Size s = Size.Empty;
		if( FuncName == ZWireFuncName.POWER ) {
			switch( DirType ) {
					case E_DirType.UP:	s = new Size( POWER_ZWireW, POWER_ZWireH ); break;
				case E_DirType.DOWN:	s = new Size( POWER_ZWireW, POWER_ZWireH ); break;
				case E_DirType.LEFT:	s = new Size( POWER_ZWireH, POWER_ZWireW ); break;
				case E_DirType.RIGHT:	s = new Size( POWER_ZWireH, POWER_ZWireW ); break;
				default:				return Size.Empty;
			}
		}
		else if( FuncName == ZWireFuncName.MOTOR || FuncName == ZWireFuncName.SERVO ) {
			switch( DirType ) {
				case E_DirType.UP:		s = new Size( MOTOR_ZWireW, MOTOR_ZWireH ); break;
				case E_DirType.DOWN:	s = new Size( MOTOR_ZWireW, MOTOR_ZWireH ); break;
				case E_DirType.LEFT:	s = new Size( MOTOR_ZWireH, MOTOR_ZWireW ); break;
				case E_DirType.RIGHT:	s = new Size( MOTOR_ZWireH, MOTOR_ZWireW ); break;
				default:				return Size.Empty;
			}
		}
		else if( FuncName == ZWireFuncName.IO3 ) {
			switch( DirType ) {
				case E_DirType.UP:		s = new Size( IO3_ZWireW, IO3_ZWireH ); break;
				case E_DirType.DOWN:	s = new Size( IO3_ZWireW, IO3_ZWireH ); break;
				case E_DirType.LEFT:	s = new Size( IO3_ZWireH, IO3_ZWireW ); break;
				case E_DirType.RIGHT:	s = new Size( IO3_ZWireH, IO3_ZWireW ); break;
				default:				return Size.Empty;
			}
		}
		else {
			//到这里说明是数据端口
			int W = DATA_ZWireW;
			int H = DATA_ZWireH;
			if ( Style == PortStyle.IO6 ) {
				//...
			}
			else if ( Style == PortStyle.IO3 ) {
				W = W * 7 / 10;
				H= H * 5 / 3;
			}
			else {
				//...
			}
			switch( DirType ) {
				case E_DirType.UP:		s = new Size( W, H ); break;
				case E_DirType.DOWN:	s = new Size( W, H ); break;
				case E_DirType.LEFT:	s = new Size( H, W ); break;
				case E_DirType.RIGHT:	s = new Size( H, W ); break;
				default:				return Size.Empty;
			}
		}
		return new Size( (int)(s.Width * Owner.CScale), (int)(s.Height * Owner.CScale) );
	}
	
	//获取端口内部尺寸
	Size GetArea0()
	{
		Size s = Size.Empty;
		if( FuncName == ZWireFuncName.POWER ) {
			switch( DirType ) {
				case E_DirType.UP:		s = new Size( POWER_ZWireW - 4, POWER_ZWireH - 4 ); break;
				case E_DirType.DOWN:	s = new Size( POWER_ZWireW - 4, POWER_ZWireH - 4 ); break;
				case E_DirType.LEFT:	s = new Size( POWER_ZWireH - 4, POWER_ZWireW - 4 ); break;
				case E_DirType.RIGHT:	s = new Size( POWER_ZWireH - 4, POWER_ZWireW - 4 ); break;
				default:				return Size.Empty;
			}
		}
		else if( FuncName == ZWireFuncName.MOTOR || FuncName == ZWireFuncName.SERVO ) {
			switch( DirType ) {
				case E_DirType.UP:		s = new Size( MOTOR_ZWireW - 4, MOTOR_ZWireH - 4 ); break;
				case E_DirType.DOWN:	s = new Size( MOTOR_ZWireW - 4, MOTOR_ZWireH - 4 ); break;
				case E_DirType.LEFT:	s = new Size( MOTOR_ZWireH - 4, MOTOR_ZWireW - 4 ); break;
				case E_DirType.RIGHT:	s = new Size( MOTOR_ZWireH - 4, MOTOR_ZWireW - 4 ); break;
				default:				return Size.Empty;
			}
		}
		else if( FuncName == ZWireFuncName.IO3 ) {
			switch( DirType ) {
				case E_DirType.UP:		s = new Size( IO3_ZWireW - 4, IO3_ZWireH - 4 ); break;
				case E_DirType.DOWN:	s = new Size( IO3_ZWireW - 4, IO3_ZWireH - 4 ); break;
				case E_DirType.LEFT:	s = new Size( IO3_ZWireH - 4, IO3_ZWireW - 4 ); break;
				case E_DirType.RIGHT:	s = new Size( IO3_ZWireH - 4, IO3_ZWireW - 4 ); break;
				default:				return Size.Empty;
			}
		}
		//到这里说明是数据端口
		else {
			//到这里说明是数据端口
			int W = DATA_ZWireW;
			int H = DATA_ZWireH;
			if ( Style == PortStyle.IO6 ) {
				//...
			}
			else if ( Style == PortStyle.IO3 ) {
				W = W * 7 / 10;
				H= H * 5 / 3;
			}
			else {
				//...
			}
			switch( DirType ) {
				case E_DirType.UP:		s = new Size( W - 4, H - 4 ); break;
				case E_DirType.DOWN:	s = new Size( W - 4, H - 4 ); break;
				case E_DirType.LEFT:	s = new Size( H - 4, W - 4 ); break;
				case E_DirType.RIGHT:	s = new Size( H - 4, W - 4 ); break;
				default:				return Size.Empty;
			}
		}
		return new Size( (int)(s.Width * Owner.CScale), (int)(s.Height * Owner.CScale) );
	}
}
}



